home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 11: TSX-11 / Linux Cubed Series 11 - TSX-11 Vol 1.iso / sbin / bootutil.1 / bootutil / bootutils / fsutil / util.c < prev   
Encoding:
C/C++ Source or Header  |  1993-07-01  |  6.1 KB  |  294 lines

  1. /*
  2.  * fs-util    A simple generic frontend for the for the fsck and mkfs
  3.  *        programs under Linux.  See the manual pages for details.
  4.  *
  5.  * Usage:    fsck [-AV] [-t fstype] [fs-options] device
  6.  *        mkfs [-V] [-t fstype] [fs-options] device< [size]
  7.  *
  8.  * Version:    @(#)fs-util.c    1.5    03/08/93
  9.  *
  10.  * Authors:    David Engel, <david@ods.com>
  11.  *        Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12.  */
  13.  
  14.  
  15. #include <sys/types.h>
  16. #include <sys/wait.h>
  17. #include <errno.h>
  18. #include <limits.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <errno.h>
  23. #include <mntent.h>
  24. #include <unistd.h>
  25. #include <getopt.h>
  26.  
  27.  
  28. #ifndef DEFAULT_FSTYPE
  29. #   define DEFAULT_FSTYPE    "minix"
  30. #endif
  31.  
  32. #define _PATH_PROG    "%s.%s"
  33. #define _PROG_FSCK    "fsck"
  34.  
  35. #define EXIT_OK          0
  36. #define EXIT_NONDESTRUCT 1
  37. #define EXIT_DESTRUCT    2
  38. #define EXIT_UNCORRECTED 4
  39. #define EXIT_ERROR       8
  40. #define EXIT_USAGE       16
  41. #define EXIT_LIBRARY     128
  42.  
  43. static char *Version = "1.7";
  44. static char *ignored_types[] = {
  45.   "ignore",
  46.   "iso9660",
  47.   "msdos",
  48.   "nfs",
  49.   "proc",
  50.   "sw",
  51.   "swap",
  52.   NULL
  53. };
  54.  
  55.  
  56. /* Execute a program. */
  57. int do_exec(char *prog, char **argv, int verbose)
  58. {
  59.     char *args[33];
  60.     register int i;
  61.     int pid, status;
  62.  
  63.     /* Build the vector. */
  64.     i = 0;
  65.     args[i++] = prog;
  66.     while(*argv != NULL && i < 32)
  67.         args[i++] = *argv++;
  68.     args[i] = NULL;
  69.  
  70.     if (verbose) {
  71.     i = 0;
  72.     while(args[i] != NULL) {
  73.         printf("%s ", args[i]);
  74.         i++;
  75.     }
  76.     printf("\n");
  77.     if (verbose > 1)
  78.         return EXIT_OK;
  79.     }
  80.  
  81.     /* Fork and execute the correct program. */
  82.     if ((pid = fork()) < 0) {
  83.         perror("fork");
  84.     status = EXIT_ERROR;
  85.     } else if (pid == 0) {
  86.     (void) execvp(args[0], args);
  87.       perror(args[0]);
  88.     exit(EXIT_ERROR);
  89.     } else {
  90.         while(wait(&status) != pid)
  91.         ;
  92.     status = WEXITSTATUS(status);
  93.     }
  94.  
  95.     return status;
  96. }
  97.  
  98.  
  99. /* Check if we have to ignore a file system type. */
  100. int ignore(char *type)
  101. {
  102.     char **ip;
  103.  
  104.     ip = ignored_types;
  105.     while (*ip != NULL) {
  106.     if (!strcmp(type, *ip))
  107.         return 1;
  108.     ip++;
  109.     }
  110.  
  111.     return 0;
  112. }
  113.  
  114.  
  115. /* Check all file systems, using the /etc/fstab table. */
  116. int check_all(int verbose, char **argv)
  117. {
  118.     char path[PATH_MAX];
  119.     char *args[33];
  120.     FILE *mntfile;
  121.     struct mntent *mp;
  122.     register int i;
  123.     int status = EXIT_OK;
  124.  
  125.     if (verbose)
  126.         printf("Checking all file systems.\n");
  127.  
  128.     /* Create an array of arguments. */
  129.     i = 0;
  130.     while (*argv != NULL && i < 32)
  131.     args[i++] = *argv++;
  132.     args[i] = NULL;
  133.     args[i + 1] = NULL;
  134.  
  135.     /* Open the mount table. */
  136.     if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
  137.     perror(MNTTAB);
  138.     exit(EXIT_ERROR);
  139.     }
  140.  
  141.     /* Walk through the /etc/fstab file. */
  142.     while ((mp = getmntent(mntfile)) != NULL) {
  143.     if (verbose)
  144.         printf("%-7s %-15s %-15s ", mp->mnt_type,
  145.            mp->mnt_fsname, mp->mnt_dir);
  146.     if (ignore(mp->mnt_type)) {
  147.         if (verbose)
  148.             printf("(ignored)\n");
  149.         continue;
  150.     }
  151.  
  152.     /* Build program name. */
  153.     sprintf(path, _PATH_PROG, _PROG_FSCK, mp->mnt_type);
  154.     args[i] = mp->mnt_fsname;
  155.     status |= do_exec(path, args, verbose);
  156.     }
  157.  
  158.     (void) endmntent(mntfile);
  159.  
  160.     return status;
  161. }
  162.  
  163.  
  164. /* Lookup filesys in /etc/fstab and return the corresponding entry. */
  165. struct mntent *lookup(char *filesys)
  166. {
  167.     FILE *mntfile;
  168.     struct mntent *mp;
  169.  
  170.     /* No filesys name given. */
  171.     if (filesys == NULL)
  172.         return NULL;
  173.  
  174.     /* Open the mount table. */
  175.     if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
  176.     perror(MNTTAB);
  177.     exit(EXIT_ERROR);
  178.     }
  179.  
  180.     while ((mp = getmntent(mntfile)) != NULL) {
  181.     if (!strcmp(filesys, mp->mnt_fsname) ||
  182.         !strcmp(filesys, mp->mnt_dir))
  183.         break;
  184.     }
  185.  
  186.     (void) endmntent(mntfile);
  187.  
  188.     return mp;
  189. }
  190.  
  191.  
  192. void usage(int fsck, char *prog)
  193. {
  194.     if (fsck) {
  195.     fprintf(stderr, "Usage: fsck [-AV] [-t fstype] [fs-options] filesys\n");
  196.     } else {
  197.     fprintf(stderr, "Usage: mkfs [-V] [-t fstype] [fs-options] filesys [size]\n");
  198.     }
  199.  
  200.     exit(EXIT_USAGE);
  201. }
  202.  
  203.  
  204. void main(int argc, char *argv[])
  205. {
  206.     char path[PATH_MAX];
  207.     char *oldpath, newpath[PATH_MAX];
  208.     register char *sp;
  209.     struct mntent *fsent;
  210.     char *fstype = NULL;
  211.     int verbose = 0;
  212.     int doall = 0;
  213.     int i, fsck, more;
  214.  
  215.     /* Must be 1 for "fsck" and 0 for "mkfs". */
  216.     if ((sp = strrchr(argv[0], '/')) != NULL)
  217.         sp++;
  218.     else
  219.         sp = argv[0];
  220.     if (!strcmp(sp, _PROG_FSCK))
  221.         fsck = 1;
  222.     else
  223.         fsck = 0;
  224.  
  225.     /* Check commandline options. */
  226.     opterr = 0;
  227.     more = 0;
  228.     while (((i = getopt(argc, argv, "AVt:")) != EOF) && (more == 0))
  229.     switch(i) {
  230.       case 'A':
  231.         doall++;
  232.         break;
  233.       case 'V':
  234.         verbose++;
  235.         break;
  236.       case 't':
  237.         if (optarg == NULL)
  238.             usage(fsck, sp);
  239.         fstype = optarg;
  240.         break;
  241.       default:
  242.         more = 1;
  243.         break;        /* start of specific arguments */
  244.     }
  245.  
  246.     /* Did we get any specific arguments? */
  247.     if (more)
  248.         optind--;
  249.  
  250.     /* Print our version number if requested. */
  251.     if (verbose)
  252.         printf("%s (fsutil) version %s (%s)\n", argv[0],
  253.            Version, __DATE__);
  254.  
  255.     /* Update our PATH to include /etc/fs and /etc. */
  256.     strcpy(newpath, "PATH=/etc/fs:/etc:");
  257.     if ((oldpath = getenv("PATH")) != NULL)
  258.         strcat(newpath, oldpath);
  259.     putenv(newpath);
  260.     
  261.     /* If -A was specified ("check all"), double-check. */
  262.     if (doall) {
  263.     if (!fsck || (fstype != NULL))
  264.         usage(fsck, sp);
  265.     exit(check_all(verbose, &argv[optind]));
  266.     } else {
  267.     /* If -t wasn't specified, we must deduce fstype. */
  268.     if (fstype == NULL) {
  269.         /* make sure that "filesys" was specified */
  270.         if (optind >= argc)
  271.         usage(fsck, sp);
  272.         /* then try looking for it in /etc/fstab */
  273.         if ((fsent = lookup(argv[argc - 1])) != NULL) {
  274.             argv[argc - 1] = fsent->mnt_fsname;
  275.         fstype = fsent->mnt_type;
  276.         } else {
  277.             if (!fsck && optind < argc-1) {
  278.             if ((fsent = lookup(argv[argc - 2])) != NULL) {
  279.                 argv[argc - 2] = fsent->mnt_fsname;
  280.             fstype = fsent->mnt_type;
  281.             }
  282.         }
  283.         }
  284.         /* if we still don't know, use the default */
  285.         if (fstype == NULL) fstype = DEFAULT_FSTYPE;
  286.     }
  287.  
  288.     /* Build program name. */
  289.     sprintf(path, _PATH_PROG, sp, fstype);
  290.     exit(do_exec(path, &argv[optind], verbose));
  291.     }
  292.     /*NOTREACHED*/
  293. }
  294.